package org.ttitfly.ttcore.web.account;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springside.modules.orm.Page;
import org.springside.modules.security.springsecurity.SpringSecurityUtils;
import org.springside.modules.utils.web.struts2.Struts2Utils;
import org.ttitfly.ttcore.entity.account.Role;
import org.ttitfly.ttcore.entity.account.User;
import org.ttitfly.ttcore.entity.menu.SystemMenu;
import org.ttitfly.ttcore.entity.system.Dictionary;
import org.ttitfly.ttcore.json.menu.FirstMenu;
import org.ttitfly.ttcore.json.menu.LeafMenu;
import org.ttitfly.ttcore.json.menu.MenuSort;
import org.ttitfly.ttcore.json.menu.SecondMenu;
import org.ttitfly.ttcore.service.ServiceException;
import org.ttitfly.ttcore.service.account.AccountManager;
import org.ttitfly.ttcore.service.account.RoleManager;
import org.ttitfly.ttcore.service.account.UserManager;
import org.ttitfly.ttcore.service.menu.SystemMenuManager;
import org.ttitfly.ttcore.service.system.DictionaryManager;
import org.ttitfly.ttcore.so.account.UserSO;
import org.ttitfly.ttcore.util.annotation.IsSearchObject;
import org.ttitfly.ttcore.util.annotation.PageSize;
import org.ttitfly.ttcore.util.web.Constants;
import org.ttitfly.ttcore.web.CrudActionSupport;

import com.google.gson.Gson;

/**
 * 用户管理Action.
 * 
 * 使用Struts2 convention-plugin annotation定义Action参数.
 * 演示带分页的管理界面.
 * 
 */

public class UserAction extends CrudActionSupport<User> {

	private static final long serialVersionUID = 8683878162525847072L;
	
	private static final String USER_PROFILE = "user_profile";
	

	private AccountManager accountManager;

	
	@PageSize(value = 20, exportLimit = 2000)
    private UserPageList pageList;

    @IsSearchObject
    private UserSO userSO;
	
    @Resource
	private UserManager userManager;
    
    @Autowired
	private SystemMenuManager systemMenuManager;

	//-- 页面属性 --//
	private Long id;
	private User entity;
	private Page<User> page = new Page<User>(5);//每页5条记录
	
	
	@Autowired
	private DictionaryManager dictionaryManager;
	
	@Autowired
	private RoleManager roleManager;
	
	//所有地区
	private List<Dictionary> areaList = new ArrayList<Dictionary>();
	
	//选中的地区
	private List<Long> areaIds = new ArrayList<Long>();
	
	//页面中钩选的角色id列表 
	private List<Long> checkedRoleIds = new ArrayList<Long>(); 
	
	//所有角色
	private List<Role> roleList = new ArrayList<Role>();
	
	private String repeatPassword;
	

	//-- ModelDriven 与 Preparable函数 --//
	public void setId(Long id) {
		this.id = id;
	}

	public User getModel() {
		return entity;
	}
	

	public  void prepare() throws Exception {
		if (id != null) {
			entity = userManager.getUser(id);
		} else {
			entity = new User();
		}
	}
	/**
	 * 分配区域和角色
	 * @return
	 */
	public String preAssignRoleAndArea2User(){
//		entity = userManager.getUser(id);
		String keyword = Constants.AREA_KEYWORD;
		Dictionary dic = dictionaryManager.findByProperty("keyword", keyword);
		if(dic.getId() != null){
			areaList = dictionaryManager.findBy("parentId", dic.getId(),"orderNum",true);
		}
		List<Dictionary> list  = entity.getAreas();
		for(Dictionary dictionary : list){
			areaIds.add(dictionary.getId());
		}
		
		roleList = roleManager.getAllRoles();
		List<Role> roles = entity.getRoles();
		for(Role role : roles){
			checkedRoleIds.add(role.getId());
		}
		
		return SUCCESS;
	}
	public String assignRoleAndArea2User(){
		List<Dictionary> list = new ArrayList<Dictionary>();
		if(areaIds.size()>0){
			list = dictionaryManager.getByIds(areaIds);
		}
		entity.setAreas(list);
		List<Role> roles  = new ArrayList<Role>();
		if(checkedRoleIds.size()>0){
			 roles = roleManager.getByIds(checkedRoleIds);
		}
		entity.setRoles(roles);
		userManager.saveUser(entity);
		
		return SUCCESS;
	}
	
	public String preCreate(){
		return SUCCESS;
	}
	
	public void  validateSave() throws Exception {
		String password = entity.getPassword();
		if(!password.equals(repeatPassword)){
			this.addFieldError("entity.password", this.getText("validation.password.unidentical"));
		}
		if(StringUtils.isNotBlank(entity.getLoginName())){
			User user = userManager.findUserByLoginName(entity.getLoginName());
			if(user != null){
				this.addFieldError("entity.loginName", this.getText("user.loginName.duplicate"));
			}
		}
	}
	/**
	 * 分配区域和角色后点确定
	 * @return
	 */
	public String save(){
		userManager.saveUser(entity);
		return SUCCESS;
	}
	
	public String preEdit() throws Exception{
		return SUCCESS;
	}
	public void  validateEdit() throws Exception {
		String password = entity.getPassword();
		if(!password.equals(repeatPassword)){
			this.addFieldError("entity.password", this.getText("validation.password.unidentical"));
		}
	}
	public String edit() throws Exception{
		userManager.saveUser(entity);
		return SUCCESS;
	}
	
	
	@Override
	public String delete() throws Exception {
		try {
			entity.setAreas(new ArrayList<Dictionary>());
			entity.setRoles(new ArrayList<Role>());
			userManager.deleteUser(entity);
//			accountManager.deleteUser(id);
			addActionMessage("删除用户成功");
		} catch (ServiceException e) {
			logger.error(e.getMessage(), e);
			addActionMessage("删除用户失败");
		}
		return SUCCESS;
	}

	@Override
	protected void prepareModel() throws Exception {
	}
	//-- CRUD Action 函数 --//
	@Override
	public String list() throws Exception {
		return SUCCESS;
	}
	
	public String listUser() throws Exception {
		
		
		return SUCCESS;
	}
	
	public String login() throws Exception{
		return SUCCESS;
	}
	
	public String loginOk() throws Exception{
		User user = getUserProfile();
		return SUCCESS;
	}
	

	public String logout() throws IOException{
		this.request.getSession().invalidate();
		return SUCCESS;
	}
	private User getUserProfile() {
		User user = new User();
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setLoginName(userDetails.getUsername());
        user.setPassword(userDetails.getPassword());
		//session中增加用户的其他信息
        user=userManager.findUserByLoginname(user.getLoginName());
        request.getSession().setAttribute(USER_PROFILE, user);
        return user;
    }
	@Override
	public String input() throws Exception {
//		checkedRoleIds = entity.getRoleIds();
		return INPUT;
	}



	//-- 其他Action函数 --//
	/**
	 * 支持使用Jquery.validate Ajax检验用户名是否重复.
	 */
	public String checkLoginName() {
		HttpServletRequest request = ServletActionContext.getRequest();
		String newLoginName = request.getParameter("loginName");
		String oldLoginName = request.getParameter("oldLoginName");

		if (accountManager.isLoginNameUnique(newLoginName, oldLoginName)) {
			Struts2Utils.renderText("true");
		} else {
			Struts2Utils.renderText("false");
		}
		//因为直接输出内容而不经过jsp,因此返回null.
		return null;
	}

	//-- 页面属性访问函数 --//
	/**
	 * list页面显示用户分页列表.
	 */
	public Page<User> getPage() {
		return page;
	}

	/**
	 * input页面显示所有角色列表.
	 */
//	public List<Role> getAllRoleList() {
//		return accountManager.getAllRole();
//	}
	
	/**
	 * input页面显示用户拥有的角色.
	 */
	public List<Long> getCheckedRoleIds() {
		return checkedRoleIds;
	}
	
	@SuppressWarnings("unchecked")
	public List<FirstMenu> processFirstMenu(Set<FirstMenu> firstMenuSet,Set<SecondMenu> secondMenuSet,Set<LeafMenu> leafMenuSet){
		List<FirstMenu> firstMenus = new ArrayList<FirstMenu>();////Json结构对象使用
		for (Iterator iterator = firstMenuSet.iterator(); iterator.hasNext();) {
			FirstMenu firstMenu = (FirstMenu) iterator.next();
			String idStr = firstMenu.getId();
			Long id = Long.valueOf(idStr);
			List<SystemMenu> secondMenuList = systemMenuManager.findBy("parentId", id,"orderNum",true);
			List<SecondMenu> secondMenus = new ArrayList<SecondMenu>();//Json结构对象使用
			for (Iterator iterator2 = secondMenuSet.iterator(); iterator2.hasNext();) {
				SecondMenu secondMenu = (SecondMenu) iterator2.next();
				boolean exist = false;
				for(SystemMenu systemMenu : secondMenuList){
					if(systemMenu.getId().longValue() == Long.valueOf(secondMenu.getId()).longValue()){
						exist = true;
						break;
					}
				}
				if(exist){
					List<LeafMenu> leafMenus = new ArrayList<LeafMenu>();////Json结构对象使用
					List<SystemMenu> leafMenuList = systemMenuManager.findBy("parentId", Long.valueOf(secondMenu.getId()),"orderNum",true);
					for (Iterator iterator3 = leafMenuSet.iterator(); iterator3
							.hasNext();) {
						boolean leafExist = false;
						LeafMenu leafMenu = (LeafMenu) iterator3.next();
						for(SystemMenu menu3 : leafMenuList){
							if(menu3.getId().longValue() == Long.valueOf(leafMenu.getId()).longValue()){
								leafExist = true;
								break;
							}
							
						}
						if(leafExist){
							leafMenus.add(leafMenu);
						}
					}
					secondMenu.setMenus(leafMenus);
					secondMenus.add(secondMenu);
				}
				
			}
			firstMenu.setMenus(secondMenus);
			firstMenus.add(firstMenu);
			
		}
		
		return firstMenus;
	}
	
	public List<FirstMenu> circleMenu(List<SystemMenu> menus){
		Set<FirstMenu> firstMenuSet = new TreeSet<FirstMenu>(new MenuSort());////Json结构对象使用
		Set<SecondMenu> secondMenuSet = new TreeSet<SecondMenu>(new MenuSort());//Json结构对象使用
		Set<LeafMenu> leafMenuSet = new TreeSet<LeafMenu>(new MenuSort());//Json结构对象使用
		
		for(SystemMenu menu : menus){
			if(menu.getLeaf().intValue()==1){//叶子
				Long parentId = menu.getParentId();
				LeafMenu leafMenu = new LeafMenu();
				leafMenu.setId(""+menu.getId());
				leafMenu.setTitle(menu.getTitle());
				leafMenu.setUrl(menu.getUrl());
				leafMenu.setStyle(menu.getStyle());
				leafMenu.setOrderNum(menu.getOrderNum());
				leafMenuSet.add(leafMenu);
				
				SystemMenu parentMenu = systemMenuManager.getById(parentId);//二级菜单
				SecondMenu secondMenu = new SecondMenu();
				secondMenu.setId(""+parentMenu.getId());
				secondMenu.setTitle(parentMenu.getTitle());
				secondMenu.setOrderNum(parentMenu.getOrderNum());
				secondMenuSet.add(secondMenu);
				
				parentMenu = systemMenuManager.getById(parentMenu.getParentId());//一级菜单
				FirstMenu firstMenu = new FirstMenu();
				firstMenu.setId(""+parentMenu.getId());
				firstMenu.setTitle(parentMenu.getTitle());
				firstMenu.setStyle(parentMenu.getStyle());
				firstMenu.setOrderNum(parentMenu.getOrderNum());
				firstMenuSet.add(firstMenu);
					
			}else {//如果是非叶子菜单，那么代表该菜单下的所有子菜单全部被选中关联。
				if(menu.getParentId() == 0){//说明是一级菜单
					FirstMenu firstMenu = new FirstMenu();
					firstMenu.setId(""+menu.getId());
					firstMenu.setTitle(menu.getTitle());
					firstMenu.setStyle(menu.getStyle());
					firstMenu.setOrderNum(menu.getOrderNum());
					firstMenuSet.add(firstMenu);
					
					List<SystemMenu> secondMenuList = systemMenuManager.findBy("parentId", Long.valueOf(firstMenu.getId()),"orderNum",true);
					for(SystemMenu systemMenu : secondMenuList){
						SecondMenu secondMenu = new SecondMenu();
						secondMenu.setId(""+systemMenu.getId());
						secondMenu.setTitle(systemMenu.getTitle());
						secondMenu.setOrderNum(systemMenu.getOrderNum());
						secondMenuSet.add(secondMenu);
						
						
						List<SystemMenu> leafMenuList = systemMenuManager.findBy("parentId", systemMenu.getId(),"orderNum",true);
						for(SystemMenu sMenu : leafMenuList){
							LeafMenu leafMenu = new LeafMenu();
							leafMenu.setId(""+sMenu.getId());
							leafMenu.setTitle(sMenu.getTitle());
							leafMenu.setUrl(sMenu.getUrl());
							leafMenu.setStyle(sMenu.getStyle());
							leafMenu.setOrderNum(sMenu.getOrderNum());
							leafMenuSet.add(leafMenu);
						}
						
					}
					
				}else{//二级菜单
					SecondMenu secondMenu = new SecondMenu();
					secondMenu.setId(""+menu.getId());
					secondMenu.setTitle(menu.getTitle());
					secondMenu.setOrderNum(menu.getOrderNum());
					secondMenuSet.add(secondMenu);
					
					
					List<SystemMenu> leafMenuList = systemMenuManager.findBy("parentId", menu.getId(),"orderNum",true);
					for(SystemMenu sMenu : leafMenuList){
						LeafMenu leafMenu = new LeafMenu();
						leafMenu.setId(""+sMenu.getId());
						leafMenu.setTitle(sMenu.getTitle());
						leafMenu.setUrl(sMenu.getUrl());
						leafMenu.setStyle(sMenu.getStyle());
						leafMenu.setOrderNum(sMenu.getOrderNum());
						leafMenuSet.add(leafMenu);
					}
					
					SystemMenu parentMenu = systemMenuManager.getById(menu.getParentId());//一级菜单
					FirstMenu firstMenu = new FirstMenu();
					firstMenu.setId(""+parentMenu.getId());
					firstMenu.setTitle(parentMenu.getTitle());
					firstMenu.setStyle(parentMenu.getStyle());
					firstMenu.setOrderNum(parentMenu.getOrderNum());
					firstMenuSet.add(firstMenu);
				}
				
				
			}
		}
		
		return processFirstMenu(firstMenuSet,secondMenuSet,leafMenuSet);
		
	}
	/**
	 * 根据用户权限获得其菜单的json格式
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public String menuJson() throws Exception{
		Set<SystemMenu> firstMenuSet = new HashSet<SystemMenu>();
		Long userId = SpringSecurityUtils.getCurrentUserId();
		User user = userManager.getUser(userId);
		String loginName = user.getLoginName();
		List<Role> roles = user.getRoles();
		
		
		for(Role role : roles){
			List<SystemMenu> menus = role.getMenus();
			for(SystemMenu menu : menus){
				firstMenuSet.add(menu);
			}
		}
		List<SystemMenu> allMenu = new ArrayList<SystemMenu>(firstMenuSet);
		Collections.sort(allMenu,new MenuSort());
		List<FirstMenu> firstMenus = circleMenu(allMenu);

		Gson gson = new Gson();
		String strGson = gson.toJson(firstMenus);
		printJson(strGson);
		return null;
	}
	
	
	

	/**
	 * input页面提交用户拥有的角色.
	 */
	public void setCheckedRoleIds(List<Long> checkedRoleIds) {
		this.checkedRoleIds = checkedRoleIds;
	}

	@Autowired
	public void setAccountManager(AccountManager accountManager) {
		this.accountManager = accountManager;
	}

	public UserPageList getPageList() {
		pageList = new UserPageList(userSO, userManager);
		return pageList;
	}

	public void setPageList(UserPageList pageList) {
		this.pageList = pageList;
	}

	public UserSO getUserSO() {
		return userSO;
	}

	public void setUserSO(UserSO userSO) {
		this.userSO = userSO;
	}

	public UserManager getUserManager() {
		return userManager;
	}

	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}

	public List<Dictionary> getAreaList() {
		return areaList;
	}

	public void setAreaList(List<Dictionary> areaList) {
		this.areaList = areaList;
	}

	public List<Long> getAreaIds() {
		return areaIds;
	}

	public void setAreaIds(List<Long> areaIds) {
		this.areaIds = areaIds;
	}

	public User getEntity() {
		return entity;
	}

	public void setEntity(User entity) {
		this.entity = entity;
	}

	public List<Role> getRoleList() {
		return roleList;
	}

	public void setRoleList(List<Role> roleList) {
		this.roleList = roleList;
	}

	public Long getId() {
		return id;
	}

	public String getRepeatPassword() {
		return repeatPassword;
	}

	public void setRepeatPassword(String repeatPassword) {
		this.repeatPassword = repeatPassword;
	}

	public String create() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
	
//	for(Role role : roles){
//	List<SystemMenu> menus = role.getMenus();
//	for(SystemMenu menu : menus){
//		if(menu.getParentId() == 0){
//			firstMenuSet.add(menu);//只添加一级菜单，并且去掉重复的
//		}
//	}
//}
//List<FirstMenu> firstMenus = new ArrayList<FirstMenu>();////Json结构对象使用
//List<SystemMenu> firstMenuList = new ArrayList<SystemMenu>(firstMenuSet);
//for(SystemMenu menu : firstMenuList){
//	FirstMenu firstMenu = new FirstMenu();
//	firstMenu.setId(""+menu.getId());
//	firstMenu.setTitle(menu.getTitle());
//	firstMenu.setStyle(menu.getStyle());
//	
//	List<SecondMenu> secondMenus = new ArrayList<SecondMenu>();//Json结构对象使用
//	List<SystemMenu> secondMenuList = systemMenuManager.findBy("parentId", menu.getId(),"orderNum",true);
//	for(SystemMenu menu2 : secondMenuList){
//		SecondMenu secondMenu = new SecondMenu();
//		secondMenu.setId(""+menu2.getId());
//		secondMenu.setTitle(menu2.getTitle());
//		
//		List<LeafMenu> leafMenus = new ArrayList<LeafMenu>();////Json结构对象使用
//		List<SystemMenu> leafMenuList = systemMenuManager.findBy("parentId", menu2.getId(),"orderNum",true);
//		for(SystemMenu menu3 : leafMenuList){
//			System.out.println(menu3.getTitle()+":"+ menu3.getOrderNum());
//			LeafMenu leafMenu = new LeafMenu();
//			leafMenu.setId(""+menu3.getId());
//			leafMenu.setTitle(menu3.getTitle());
//			leafMenu.setUrl(menu3.getUrl());
//			leafMenu.setStyle(menu3.getStyle());
//			leafMenus.add(leafMenu);
//		}
//		secondMenu.setMenus(leafMenus);
//		secondMenus.add(secondMenu);
//		
//	}
//	firstMenu.setMenus(secondMenus);
//	firstMenus.add(firstMenu);
//}
//
}
